﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//
using System.Diagnostics;
using System.Collections;
using System.IO;
using System.Net;

// MobiLib, Copyright Mirosław M. Mączka.  All Rights Reserved. This code released under the terms of the Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.)

namespace MobiLibrary
{
    //
    public partial class MobiLib
    {
        //==================================================================================================================================
        //
        public static short Bytes2Short(byte[] bb, int offset)
        {
            byte[] b = new byte[2];

            Array.Copy(bb, offset, b, 0, b.Length);
            Array.Reverse(b);
            return BitConverter.ToInt16(b, 0);
        }
        //
        public static short Short2Bytes(short v, byte[] bb, int offset)
        {
            byte[] b = BitConverter.GetBytes(v);
            Array.Reverse(b);
            Array.Copy(b, 0, bb, offset, 2);
            return v;
        }
        //
        //----------------------------------------------------------------------------------------------------------------------------------
        //
        public static int Bytes2Int(byte[] bb, int offset)
        {
            byte[] b = new byte[4];
            Array.Copy(bb, offset, b, 0, b.Length);
            Array.Reverse(b);
            return BitConverter.ToInt32(b, 0);
        }
        //
        public static int Int2Bytes(int v, byte[] bb, int offset)
        {
            byte[] b = BitConverter.GetBytes(v);
            Array.Reverse(b);
            Array.Copy(b, 0, bb, offset, 4);
            return v;
        }
        //
        //----------------------------------------------------------------------------------------------------------------------------------
        //
        public static string Bytes2String(byte[] bb, int offset, int maxlength)
        {
            for (int i = maxlength - 1; i >= 0; i--)
            {
                if (0 == bb[offset + i]) maxlength--;
                else break;
            }
            return System.Text.Encoding.UTF8.GetString(bb, offset, maxlength);
        }
        //
        /// <summary>
        /// Wpisuje string s w tablicę bajtów bb (kodowanie UTF8), dodając zerowy bajt na końcu
        /// </summary>
        /// <param name="s">string wejściowy</param>
        /// <param name="bb">docelowa tablica bajtów</param>
        /// <param name="offset">od którego bajtu w bb</param>
        /// <param name="maxlength">maksymalna długość stringu</param>
        /// <returns></returns>
        public static int String2Bytes(string s, byte[] bb, int offset, int maxlength)
        {
            byte[] b = System.Text.Encoding.UTF8.GetBytes(s);
            //
            Array.Clear(bb, offset, maxlength);
            Array.Copy(b, 0, bb, offset, Math.Min(b.Length, (maxlength - 1)));
            //
            return s.Length;
        }
        //
        /// <summary>
        /// Wpisuje string s w tablicę bajtów bb (kodowanie UTF8), BEZ zerowego bajta na końcu
        /// </summary>
        /// <param name="s">string wejściowy</param>
        /// <param name="bb">docelowa tablica bajtów</param>
        /// <param name="offset">od którego bajtu w bb</param>
        /// <param name="maxlength">maksymalna długość stringu</param>
        /// <returns></returns>
        public static int String2BytesWZ(string s, byte[] bb, int offset, int maxlength)
        {
            byte[] b = System.Text.Encoding.UTF8.GetBytes(s);
            //
            Array.Copy(b, bb, maxlength);
            //
            return s.Length;
        }
        /// <summary>
        /// Zamienia string s na tablicę bajtów (kodowanie UTF8), dodając zerowy bajt na końcu
        /// </summary>
        /// <param name="s">string</param>
        /// <returns>tablica bajtów</returns>
        public static byte[] String2ByteArray(string s)
        {
            return System.Text.Encoding.UTF8.GetBytes(s);
        }
        public static int String2BytesWA(string s, byte[] bb, int offset, int maxlength)
        {
            s=Utils.RemoveAccents(s);
            s = s.Replace("  ", " ");
            s = s.Trim();
            return String2Bytes(s, bb, offset, maxlength);
        }
        //
        //----------------------------------------------------------------------------------------------------------------------------------
        //
        public static DateTime Bytes2DateTime(byte[] bb, int offset)
        {
            //No. of seconds since start of January 1, 1904. == 600527520000000000
            UInt32 dt_prc = (UInt32)Bytes2Int(bb, offset);
            Int64 dtt = dt_prc * 10000000L;// sec --> 100ns
            if (0 != (dt_prc & 0x80000000L))
            {
                dtt += 600527520000000000L;//mac January 1, 1904
            }
            else
            {
                dtt += 621355968000000000L;//unix January 1, 1970
            }
            DateTime dt = new DateTime(dtt);
            return dt;
        }
        //
        public static int DateTime2Bytes(DateTime dt, byte[] bb, int offset)
        {
            //Int64 dtt = dt.Ticks - 621355968000000000L; dtt /= 10000000L;//unix
            Int64 dtt = dt.Ticks - 600527520000000000L; dtt /= 10000000L; dtt |= 0x80000000L;//mac
            return Int2Bytes((int)dtt, bb, offset);
        }
        //
        //----------------------------------------------------------------------------------------------------------------------------------
        //
        private byte[] CopyBlock(byte[] bb, int offset, int length)
        {
            byte[] b = new byte[length]; Array.Copy(bb, offset, b, 0, length);
            return b;
        }
        //
        [Conditional("DEBUG")]
        private void DumpAsBin(string f, byte[] bin)
        {
            File.WriteAllBytes(f, bin);
        }
        //
        //==================================================================================================================================
    }//class
}//namespace
